package com.DJRelayAndroidClient_ACE.djrelay_androidclient;

/*
 * Copyright (c) 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

/* Modified on 23-June-2013 for DJ Relay Integration */

import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.ResourceId;
import com.google.api.services.youtube.model.SearchListResponse;
import com.google.api.services.youtube.model.SearchResult;
import com.google.api.services.youtube.model.Thumbnail;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**
 * Prints a list of videos based on a search term.
 *
 * @author Jeremy Walker
 */
public class SearchActivity extends Activity {

  /** Global instance of the HTTP transport. */
  private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  /** Global instance of the JSON factory. */
  private static final JsonFactory JSON_FACTORY = new JacksonFactory();

  /** Global instance of the max number of videos we want returned (50 = upper limit per page). */
  private static final long NUMBER_OF_VIDEOS_RETURNED = 25;

  /** Selected song title returned to main activity  **/
  static final String SONG_TITLE = null;
  
  /** Selected video URL returned to main activity   **/
  static final String SONG_ID = null;
  
  /** Selected video data returned to main activity   **/
  static final String SONG_DATA = null;

  /** Global instance of YouTube object to make all API requests. */
  private static YouTube youtube;
  
  private static Context context;
  
  private Button TubeSearch;
  private EditText TubeEntry;
  private ListView TubeListView;
  private static ArrayList<String> tubeList;
  private static ArrayList<String> tubeListID;		// TODO - probably should just link this data to the 
  													// tubeList, don't feel like figuring this out now..
  private String searchInput;
  
  private YouTube.Search.List search;
  private SearchListResponse searchResponse;
  private List<SearchResult> searchResultList;
  
  private static StableArrayAdapter tubeAdapter;
  
  /**
   * Initializes YouTube object to search for videos on YouTube (Youtube.Search.List). The program
   * then prints the names and thumbnails of each of the videos (only first 50 videos).
   *
   */
  @Override
  public void onCreate(Bundle savedInstanceState) {
	  super.onCreate(savedInstanceState);
	  setContentView(R.layout.youtube_view);	  
      context = getApplicationContext();
      
      tubeList = new ArrayList<String>();
      tubeListID = new ArrayList<String>();
      tubeAdapter = new StableArrayAdapter(this, android.R.layout.simple_list_item_1, tubeList);
	  
	  TubeSearch = (Button) findViewById(R.id.tubeSearchButton);
      TubeSearch.setOnClickListener(mTubeSearchListener);
      
      TubeEntry = (EditText) findViewById(R.id.tubeTextEntry);
      
      TubeListView = (ListView) findViewById(R.id.tubeListView);
      TubeListView.setAdapter(tubeAdapter);
      TubeListView.setOnItemClickListener(mItemListener);
		  	  
      try {
      /*
      * The YouTube object is used to make all API requests. The last argument is required, but
      * because we don't need anything initialized when the HttpRequest is initialized, we override
      * the interface and provide a no-op function.
      */
    	  
    	  youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, new HttpRequestInitializer() {
    		  public void initialize(HttpRequest request) throws IOException {}
    	  	  }).setApplicationName("DJ Relay").build();    	  

          search = youtube.search().list("id,snippet");

	/*
       * It is important to set your developer key from the Google Developer Console for
       * non-authenticated requests (found under the API Access tab at this link:
       * code.google.com/apis/). This is good practice and increased your quota.
       */
      String apiKey = DeveloperKey.DEVELOPER_KEY;
      search.setKey(apiKey);

    } catch (GoogleJsonResponseException e) {
      System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
          + e.getDetails().getMessage());
    } catch (IOException e) {
      System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
  
  private OnClickListener mTubeSearchListener = new OnClickListener() {
	  public void onClick(View button) {
		  // Force keyboard hidden on submit button press
		  InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
		    imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
		    
		  searchInput = TubeEntry.getText().toString();
	      //search.setQ(searchInput + " (High Quality)");	// Maybe add some button or something for this
		  search.setQ(searchInput);
	      /*
	       * We are only searching for videos (not playlists or channels). If we were searching for
	       * more, we would add them as a string like this: "video,playlist,channel".
	       */
	      search.setType("video");
	      /*
	       * This method reduces the info returned to only the fields we need and makes calls more
	       * efficient.
	       */
	      // TODO - also need some checking against videos that can't be played in mobile player..
	      search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
	      search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);
		  new Thread (new Runnable() {
			  public void run() {
				  try {
					  searchResponse = search.execute();
					  searchResultList = searchResponse.getItems();
				      runOnUiThread(new Runnable () {	
				    	  public void run() {
				    		  prettyPrint(searchResultList.iterator(), searchInput);
				    	  }
				      });					  
					  
				  } catch (IOException e) {
					  // TODO Auto-generated catch block
					  e.printStackTrace();
				  }		      				  
		      }			  
		 }).start();		  
	  }	  
  };  
  
  private OnItemClickListener mItemListener = new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView<?> parent, final View view,
          int position, long id) {

        String mSong = tubeList.get(position);
        String mSongID = tubeListID.get(position);
        
        Bundle extras = new Bundle();
        extras.putString("SONG_TITLE", mSong);
        extras.putString("SONG_ID", mSongID);
        getIntent().putExtras(extras);

        setResult(RESULT_OK, getIntent());
        finish();
      }
  };

  /*
   * Prints out all SearchResults in the Iterator. Each printed line includes title, id, and
   * thumbnail.
   *
   * @param iteratorSearchResults Iterator of SearchResults to print
   *
   * @param query Search query (String)
   */
  private static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {
	  
	tubeList.clear();
	tubeAdapter.notifyDataSetChanged();
	
	tubeListID.clear();

    System.out.println("\n=============================================================");
    System.out.println(
        "   First " + NUMBER_OF_VIDEOS_RETURNED + " videos for search on \"" + query + "\".");
    System.out.println("=============================================================\n");

    if (!iteratorSearchResults.hasNext()) {
      System.out.println(" There aren't any results for your query.");
      tubeList.clear();		
      tubeAdapter.notifyDataSetChanged();
      tubeListID.clear();
      Toast toast = Toast.makeText(context, "No results for your search", Toast.LENGTH_SHORT);
      toast.show();
    }
    
    int i = 0;	//debug purpose
    while (iteratorSearchResults.hasNext()) {

      SearchResult singleVideo = iteratorSearchResults.next();
      ResourceId rId = singleVideo.getId();

      // Double checks the kind is video.
      if (rId.getKind().equals("youtube#video")) {
        Thumbnail thumbnail = (Thumbnail) singleVideo.getSnippet().getThumbnails().get("default");
        String videoId = rId.getVideoId();
        System.out.println(" Video Id" + videoId);
        String videoURL = "https://www.youtube.com/watch?v=" + videoId.replaceFirst("id", "");
        System.out.println(" Video URL: " + videoURL);
        String vidTitle = singleVideo.getSnippet().getTitle();
        System.out.println(" Title: " + vidTitle);
        System.out.println(" Thumbnail: " + thumbnail.getUrl());
        System.out.println("\n-------------------------------------------------------------\n");
        
        tubeList.add(vidTitle);
        tubeAdapter.notifyDataSetChanged();
        tubeListID.add(videoId);
        Log.d("myApp", tubeList.get(i++) + "Index = " + i);
      }
    }
  }
  
  @Override
  public void onStart() {
      super.onStart();   
  }

  @Override
  public synchronized void onResume() {
      super.onResume();
  }
  
  @Override
  public synchronized void onPause() {
      super.onPause();
  }

  @Override
  public void onStop() {
      super.onStop(); 
  }
  
  @Override
  public void onDestroy() {
      super.onDestroy();
  }
  
}
